home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / getchar.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  52KB  |  2,216 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * getchar.c
  11.  *
  12.  * functions related with getting a character from the user/mapping/redo/...
  13.  *
  14.  * manipulations with redo buffer and stuff buffer
  15.  * mappings and abbreviations
  16.  */
  17.  
  18. #include "vim.h"
  19. #include "globals.h"
  20. #include "proto.h"
  21. #include "option.h"
  22.  
  23. /*
  24.  * structure used to store one block of the stuff/redo/macro buffers
  25.  */
  26. struct bufblock
  27. {
  28.         struct bufblock *b_next;        /* pointer to next bufblock */
  29.         char_u            b_str[1];        /* contents (actually longer) */
  30. };
  31.  
  32. #define MINIMAL_SIZE 20                 /* minimal size for b_str */
  33.  
  34. /*
  35.  * header used for the stuff buffer and the redo buffer
  36.  */
  37. struct buffheader
  38. {
  39.         struct bufblock bh_first;        /* first (dummy) block of list */
  40.         struct bufblock *bh_curr;        /* bufblock for appending */
  41.         int             bh_index;        /* index for reading */
  42.         int             bh_space;        /* space in bh_curr for appending */
  43. };
  44.  
  45. static struct buffheader stuffbuff = {{NULL, {NUL}}, NULL, 0, 0};
  46. static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  47. static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
  48. static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
  49.  
  50. /*
  51.  * when block_redo is TRUE redo buffer will not be changed
  52.  * used by edit() to repeat insertions and 'V' command for redoing
  53.  */
  54. static int        block_redo = FALSE;
  55.  
  56. /*
  57.  * structure used for mapping
  58.  */
  59. struct mapblock
  60. {
  61.     struct mapblock *m_next;        /* next mapblock */
  62.     char_u            *m_keys;        /* mapped from */
  63.     int                 m_keylen;        /* strlen(m_keys) */
  64.     char_u            *m_str;         /* mapped to */
  65.     int              m_mode;        /* valid mode */
  66.     int                 m_noremap;        /* if non-zero no re-mapping for m_str */
  67. };
  68.  
  69. static struct mapblock maplist = {NULL, NULL, 0, NULL, 0, 0};
  70.                                     /* first dummy entry in maplist */
  71.  
  72. /*
  73.  * variables used by vgetorpeek() and flush_buffers()
  74.  *
  75.  * typebuf[] contains all characters that are not consumed yet.
  76.  * typebuf[typeoff] is the first valid character in typebuf[].
  77.  * typebuf[typeoff + typelen - 1] is the last valid char.
  78.  * typebuf[typeoff + typelen] must be NUL.
  79.  * The part in front may contain the result of mappings, abbreviations and
  80.  * @a commands. The length of this part is typemaplen.
  81.  * After it are characters that come from the terminal.
  82.  * no_abbr_cnt is the number of characters in typebuf that should not be
  83.  * considered for abbreviations.
  84.  * Some parts of typebuf may not be mapped. These parts are remembered in
  85.  * noremapbuf, which is the same length as typebuf and contains TRUE for the
  86.  * characters that are not to be remapped. noremapbuf[typeoff] is the first
  87.  * valid flag.
  88.  * (typebuf has been put in globals.h, because check_termcode() needs it).
  89.  */
  90. static char_u    *noremapbuf = NULL;       /* flags for typeahead characters */
  91. #define TYPELEN_INIT    (3 * (MAXMAPLEN + 3))
  92. static char_u    typebuf_init[TYPELEN_INIT];            /* initial typebuf */
  93. static char_u    noremapbuf_init[TYPELEN_INIT];        /* initial noremapbuf */
  94.  
  95. static int        typemaplen = 0;        /* nr of mapped characters in typebuf */
  96. static int        no_abbr_cnt = 0;    /* nr of chars without abbrev. in typebuf */
  97. static int        last_recorded_len = 0;    /* number of last recorded chars */
  98.  
  99. static void        free_buff __ARGS((struct buffheader *));
  100. static char_u    *get_bufcont __ARGS((struct buffheader *, int));
  101. static void        add_buff __ARGS((struct buffheader *, char_u *));
  102. static void        add_num_buff __ARGS((struct buffheader *, long));
  103. static void        add_char_buff __ARGS((struct buffheader *, int));
  104. static int        read_stuff __ARGS((int));
  105. static void        start_stuff __ARGS((void));
  106. static int        read_redo __ARGS((int, int));
  107. static void        copy_redo __ARGS((int));
  108. static void        init_typebuf __ARGS((void));
  109. static void        gotchars __ARGS((char_u *, int));
  110. static int        vgetorpeek __ARGS((int));
  111. static int        inchar __ARGS((char_u *, int, long));
  112. static void        map_free __ARGS((struct mapblock *));
  113. static void        showmap __ARGS((struct mapblock *));
  114.  
  115. /*
  116.  * free and clear a buffer
  117.  */
  118.     static void
  119. free_buff(buf)
  120.     struct buffheader *buf;
  121. {
  122.         register struct bufblock *p, *np;
  123.  
  124.         for (p = buf->bh_first.b_next; p != NULL; p = np)
  125.         {
  126.                 np = p->b_next;
  127.                 vim_free(p);
  128.         }
  129.         buf->bh_first.b_next = NULL;
  130. }
  131.  
  132. /*
  133.  * return the contents of a buffer as a single string
  134.  */
  135.     static char_u *
  136. get_bufcont(buffer, dozero)
  137.     struct buffheader    *buffer;
  138.     int                    dozero;        /* count == zero is not an error */
  139. {
  140.     long_u            count = 0;
  141.     char_u            *p = NULL;
  142.     char_u            *p2;
  143.     char_u            *str;
  144.     struct bufblock    *bp;
  145.  
  146. /* compute the total length of the string */
  147.     for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  148.         count += STRLEN(bp->b_str);
  149.  
  150.     if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
  151.     {
  152.         p2 = p;
  153.         for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
  154.             for (str = bp->b_str; *str; )
  155.                 *p2++ = *str++;
  156.         *p2 = NUL;
  157.     }
  158.     return (p);
  159. }
  160.  
  161. /*
  162.  * return the contents of the record buffer as a single string
  163.  *    and clear the record buffer
  164.  */
  165.     char_u *
  166. get_recorded()
  167. {
  168.     char_u *p;
  169.     size_t    len;
  170.  
  171.     p = get_bufcont(&recordbuff, TRUE);
  172.     free_buff(&recordbuff);
  173.     /*
  174.      * Remove the characters that were added the last time, these must be the
  175.      * (possibly mapped) characters that stopped recording.
  176.      */
  177.     len = STRLEN(p);
  178.     if ((int)len >= last_recorded_len)
  179.         p[len - last_recorded_len] = NUL;
  180.     return (p);
  181. }
  182.  
  183. /*
  184.  * return the contents of the redo buffer as a single string
  185.  */
  186.     char_u *
  187. get_inserted()
  188. {
  189.         return(get_bufcont(&redobuff, FALSE));
  190. }
  191.  
  192. /*
  193.  * add string "s" after the current block of buffer "buf"
  194.  */
  195.     static void
  196. add_buff(buf, s)
  197.     register struct buffheader    *buf;
  198.     char_u                        *s;
  199. {
  200.     struct bufblock *p;
  201.     long_u             n;
  202.     long_u             len;
  203.  
  204.     if ((n = STRLEN(s)) == 0)                /* don't add empty strings */
  205.         return;
  206.  
  207.     if (buf->bh_first.b_next == NULL)        /* first add to list */
  208.     {
  209.         buf->bh_space = 0;
  210.         buf->bh_curr = &(buf->bh_first);
  211.     }
  212.     else if (buf->bh_curr == NULL)            /* buffer has already been read */
  213.     {
  214.         EMSG("Add to read buffer");
  215.         return;
  216.     }
  217.     else if (buf->bh_index != 0)
  218.         STRCPY(buf->bh_first.b_next->b_str,
  219.                                  buf->bh_first.b_next->b_str + buf->bh_index);
  220.     buf->bh_index = 0;
  221.  
  222.     if (buf->bh_space >= (int)n)
  223.     {
  224.         strcat((char *)buf->bh_curr->b_str, (char *)s);
  225.         buf->bh_space -= n;
  226.     }
  227.     else
  228.     {
  229.         if (n < MINIMAL_SIZE)
  230.             len = MINIMAL_SIZE;
  231.         else
  232.             len = n;
  233.         p = (struct bufblock *)lalloc((long_u)(sizeof(struct bufblock) + len), TRUE);
  234.         if (p == NULL)
  235.             return; /* no space, just forget it */
  236.         buf->bh_space = len - n;
  237.         STRCPY(p->b_str, s);
  238.  
  239.         p->b_next = buf->bh_curr->b_next;
  240.         buf->bh_curr->b_next = p;
  241.         buf->bh_curr = p;
  242.     }
  243.     return;
  244. }
  245.  
  246.     static void
  247. add_num_buff(buf, n)
  248.     struct buffheader *buf;
  249.     long               n;
  250. {
  251.         char_u    number[32];
  252.  
  253.         sprintf((char *)number, "%ld", n);
  254.         add_buff(buf, number);
  255. }
  256.  
  257.     static void
  258. add_char_buff(buf, c)
  259.     struct buffheader *buf;
  260.     int               c;
  261. {
  262.     char_u    temp[4];
  263.  
  264.     /*
  265.      * translate special key code into three byte sequence
  266.      */
  267.     if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL)
  268.     {
  269.         temp[0] = K_SPECIAL;
  270.         temp[1] = K_SECOND(c);
  271.         temp[2] = K_THIRD(c);
  272.         temp[3] = NUL;
  273.     }
  274.     else
  275.     {
  276.         temp[0] = c;
  277.         temp[1] = NUL;
  278.     }
  279.     add_buff(buf, temp);
  280. }
  281.  
  282. /*
  283.  * get one character from the stuff buffer
  284.  * If advance == TRUE go to the next char.
  285.  */
  286.     static int
  287. read_stuff(advance)
  288.     int            advance;
  289. {
  290.     register char_u c;
  291.     register struct bufblock *curr;
  292.  
  293.  
  294.     if (stuffbuff.bh_first.b_next == NULL)    /* buffer is empty */
  295.         return NUL;
  296.  
  297.     curr = stuffbuff.bh_first.b_next;
  298.     c = curr->b_str[stuffbuff.bh_index];
  299.  
  300.     if (advance)
  301.     {
  302.         if (curr->b_str[++stuffbuff.bh_index] == NUL)
  303.         {
  304.             stuffbuff.bh_first.b_next = curr->b_next;
  305.             vim_free(curr);
  306.             stuffbuff.bh_index = 0;
  307.         }
  308.     }
  309.     return c;
  310. }
  311.  
  312. /*
  313.  * prepare stuff buffer for reading (if it contains something)
  314.  */
  315.     static void
  316. start_stuff()
  317. {
  318.     if (stuffbuff.bh_first.b_next != NULL)
  319.     {
  320.         stuffbuff.bh_curr = &(stuffbuff.bh_first);
  321.         stuffbuff.bh_space = 0;
  322.     }
  323. }
  324.  
  325. /*
  326.  * check if the stuff buffer is empty
  327.  */
  328.     int
  329. stuff_empty()
  330. {
  331.     return (stuffbuff.bh_first.b_next == NULL);
  332. }
  333.  
  334. /*
  335.  * Remove the contents of the stuff buffer and the mapped characters in the
  336.  * typeahead buffer (used in case of an error). If 'typeahead' is true,
  337.  * flush all typeahead characters (used when interrupted by a CTRL-C).
  338.  */
  339.     void
  340. flush_buffers(typeahead)
  341.     int typeahead;
  342. {
  343.     init_typebuf();
  344.  
  345.     start_stuff();
  346.     while (read_stuff(TRUE) != NUL)
  347.         ;
  348.  
  349.     if (typeahead)            /* remove all typeahead */
  350.     {
  351.             /*
  352.              * We have to get all characters, because we may delete the first
  353.              * part of an escape sequence.
  354.              * In an xterm we get one char at a time and we have to get them
  355.              * all.
  356.              */
  357.         while (inchar(typebuf, MAXMAPLEN, 10L))    
  358.             ;
  359.         typeoff = MAXMAPLEN;
  360.         typelen = 0;
  361.     }
  362.     else                    /* remove mapped characters only */
  363.     {
  364.         typeoff += typemaplen;
  365.         typelen -= typemaplen;
  366.     }
  367.     typemaplen = 0;
  368.     no_abbr_cnt = 0;
  369. }
  370.  
  371. /*
  372.  * The previous contents of the redo buffer is kept in old_redobuffer.
  373.  * This is used for the CTRL-O <.> command in insert mode.
  374.  */
  375.     void
  376. ResetRedobuff()
  377. {
  378.     if (!block_redo)
  379.     {
  380.         free_buff(&old_redobuff);
  381.         old_redobuff = redobuff;
  382.         redobuff.bh_first.b_next = NULL;
  383.     }
  384. }
  385.  
  386.     void
  387. AppendToRedobuff(s)
  388.     char_u           *s;
  389. {
  390.     if (!block_redo)
  391.         add_buff(&redobuff, s);
  392. }
  393.  
  394.     void
  395. AppendCharToRedobuff(c)
  396.     int               c;
  397. {
  398.     if (!block_redo)
  399.         add_char_buff(&redobuff, c);
  400. }
  401.  
  402.     void
  403. AppendNumberToRedobuff(n)
  404.     long             n;
  405. {
  406.     if (!block_redo)
  407.         add_num_buff(&redobuff, n);
  408. }
  409.  
  410.     void
  411. stuffReadbuff(s)
  412.     char_u           *s;
  413. {
  414.     add_buff(&stuffbuff, s);
  415. }
  416.  
  417.     void
  418. stuffcharReadbuff(c)
  419.     int               c;
  420. {
  421.     add_char_buff(&stuffbuff, c);
  422. }
  423.  
  424.     void
  425. stuffnumReadbuff(n)
  426.     long    n;
  427. {
  428.     add_num_buff(&stuffbuff, n);
  429. }
  430.  
  431. /*
  432.  * Read a character from the redo buffer.
  433.  * The redo buffer is left as it is.
  434.  * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
  435.  * otherwise
  436.  * if old is TRUE, use old_redobuff instead of redobuff
  437.  */
  438.     static int
  439. read_redo(init, old_redo)
  440.     int            init;
  441.     int            old_redo;
  442. {
  443.     static struct bufblock    *bp;
  444.     static char_u            *p;
  445.     int                        c;
  446.  
  447.     if (init)
  448.     {
  449.         if (old_redo)
  450.             bp = old_redobuff.bh_first.b_next;
  451.         else
  452.             bp = redobuff.bh_first.b_next;
  453.         if (bp == NULL)
  454.             return FAIL;
  455.         p = bp->b_str;
  456.         return OK;
  457.     }
  458.     if ((c = *p) != NUL)
  459.     {
  460.         if (c == K_SPECIAL)
  461.         {
  462.             c = TO_SPECIAL(p[1], p[2]);
  463.             p += 2;
  464.         }
  465.         if (*++p == NUL && bp->b_next != NULL)
  466.         {
  467.             bp = bp->b_next;
  468.             p = bp->b_str;
  469.         }
  470.     }
  471.     return c;
  472. }
  473.  
  474. /*
  475.  * copy the rest of the redo buffer into the stuff buffer (could be done faster)
  476.  * if old_redo is TRUE, use old_redobuff instead of redobuff
  477.  */
  478.     static void
  479. copy_redo(old_redo)
  480.     int        old_redo;
  481. {
  482.     register int c;
  483.  
  484.     while ((c = read_redo(FALSE, old_redo)) != NUL)
  485.         stuffcharReadbuff(c);
  486. }
  487.  
  488. /*
  489.  * Stuff the redo buffer into the stuffbuff.
  490.  * Insert the redo count into the command.
  491.  * If 'old_redo' is TRUE, the last but one command is repeated
  492.  * instead of the last command (inserting text). This is used for
  493.  * CTRL-O <.> in insert mode
  494.  *
  495.  * return FAIL for failure, OK otherwise
  496.  */
  497.     int
  498. start_redo(count, old_redo)
  499.     long    count;
  500.     int        old_redo;
  501. {
  502.     register int c;
  503.  
  504.     if (read_redo(TRUE, old_redo) == FAIL)    /* init the pointers; return if nothing to redo */
  505.         return FAIL;
  506.  
  507.     c = read_redo(FALSE, old_redo);
  508.  
  509. /* copy the buffer name, if present */
  510.     if (c == '"')
  511.     {
  512.         add_buff(&stuffbuff, (char_u *)"\"");
  513.         c = read_redo(FALSE, old_redo);
  514.  
  515. /* if a numbered buffer is used, increment the number */
  516.         if (c >= '1' && c < '9')
  517.             ++c;
  518.         add_char_buff(&stuffbuff, c);
  519.         c = read_redo(FALSE, old_redo);
  520.     }
  521.  
  522.     if (c == 'v')    /* redo Visual */
  523.     {
  524.         VIsual = curwin->w_cursor;
  525.         VIsual_active = TRUE;
  526.         redo_VIsual_busy = TRUE;
  527.         c = read_redo(FALSE, old_redo);
  528.     }
  529.  
  530. /* try to enter the count (in place of a previous count) */
  531.     if (count)
  532.     {
  533.         while (isdigit(c))        /* skip "old" count */
  534.             c = read_redo(FALSE, old_redo);
  535.         add_num_buff(&stuffbuff, count);
  536.     }
  537.  
  538. /* copy from the redo buffer into the stuff buffer */
  539.     add_char_buff(&stuffbuff, c);
  540.     copy_redo(old_redo);
  541.     return OK;
  542. }
  543.  
  544. /*
  545.  * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
  546.  * the redo buffer into the stuffbuff.
  547.  * return FAIL for failure, OK otherwise
  548.  */
  549.     int
  550. start_redo_ins()
  551. {
  552.     register int c;
  553.  
  554.     if (read_redo(TRUE, FALSE) == FAIL)
  555.         return FAIL;
  556.     start_stuff();
  557.  
  558. /* skip the count and the command character */
  559.     while ((c = read_redo(FALSE, FALSE)) != NUL)
  560.     {
  561.         c = TO_UPPER(c);
  562.         if (vim_strchr((char_u *)"AIRO", c) != NULL)
  563.         {
  564.             if (c == 'O')
  565.                 stuffReadbuff(NL_STR);
  566.             break;
  567.         }
  568.     }
  569.  
  570. /* copy the typed text from the redo buffer into the stuff buffer */
  571.     copy_redo(FALSE);
  572.     block_redo = TRUE;
  573.     return OK;
  574. }
  575.  
  576.     void
  577. set_redo_ins()
  578. {
  579.     block_redo = TRUE;
  580. }
  581.  
  582.     void
  583. stop_redo_ins()
  584. {
  585.     block_redo = FALSE;
  586. }
  587.  
  588. /*
  589.  * Initialize typebuf to point to typebuf_init.
  590.  * Alloc() cannot be used here: In out-of-memory situations it would
  591.  * be impossible to type anything.
  592.  */
  593.     static void
  594. init_typebuf()
  595. {
  596.     if (typebuf == NULL)
  597.     {
  598.         typebuf = typebuf_init;
  599.         noremapbuf = noremapbuf_init;
  600.         typebuflen = TYPELEN_INIT;
  601.         typelen = 0;
  602.         typeoff = 0;
  603.     }
  604. }
  605.  
  606. /*
  607.  * insert a string in position 'offset' in the typeahead buffer (for "@r"
  608.  * and ":normal" command, vgetorpeek() and check_termcode())
  609.  *
  610.  * If noremap is 0, new string can be mapped again.
  611.  * If noremap is -1, new string cannot be mapped again.
  612.  * If noremap is >0, that many characters of the new string cannot be mapped.
  613.  *
  614.  * If nottyped is TRUE, the string does not return KeyTyped (don't use when
  615.  * offset is non-zero!).
  616.  *
  617.  * return FAIL for failure, OK otherwise
  618.  */
  619.     int
  620. ins_typebuf(str, noremap, offset, nottyped)
  621.     char_u    *str;
  622.     int        noremap;
  623.     int        offset;
  624.     int        nottyped;
  625. {
  626.     register char_u    *s1, *s2;
  627.     register int    newlen;
  628.     register int    addlen;
  629.     register int    i;
  630.     register int    newoff;
  631.  
  632.     init_typebuf();
  633.  
  634.     addlen = STRLEN(str);
  635.     /*
  636.      * Easy case: there is room in front of typebuf[typeoff]
  637.      */
  638.     if (offset == 0 && addlen <= typeoff)
  639.     {
  640.         typeoff -= addlen;
  641.         vim_memmove(typebuf + typeoff, str, (size_t)addlen);
  642.     }
  643.     /*
  644.      * Need to allocate new buffer.
  645.      * In typebuf there must always be room for MAXMAPLEN + 4 characters.
  646.      * We add some extra room to avoid having to allocate too often.
  647.      */
  648.     else
  649.     {
  650.         newoff = MAXMAPLEN + 4;
  651.         newlen = typelen + addlen + newoff + 2 * (MAXMAPLEN + 4);
  652.         if (newlen < 0)                /* string is getting too long */
  653.         {
  654.             emsg(e_toocompl);        /* also calls flush_buffers */
  655.             setcursor();
  656.             return FAIL;
  657.         }
  658.         s1 = alloc(newlen);
  659.         if (s1 == NULL)                /* out of memory */
  660.             return FAIL;
  661.         s2 = alloc(newlen);
  662.         if (s2 == NULL)                /* out of memory */
  663.         {
  664.             vim_free(s1);
  665.             return FAIL;
  666.         }
  667.         typebuflen = newlen;
  668.  
  669.                 /* copy the old chars, before the insertion point */
  670.         vim_memmove(s1 + newoff, typebuf + typeoff, (size_t)offset);
  671.                 /* copy the new chars */
  672.         vim_memmove(s1 + newoff + offset, str, (size_t)addlen);
  673.                 /* copy the old chars, after the insertion point, including
  674.                  * the  NUL at the end */
  675.         vim_memmove(s1 + newoff + offset + addlen, typebuf + typeoff + offset,
  676.                                               (size_t)(typelen - offset + 1));
  677.         if (typebuf != typebuf_init)
  678.             vim_free(typebuf);
  679.         typebuf = s1;
  680.  
  681.         vim_memmove(s2 + newoff, noremapbuf + typeoff, (size_t)offset);
  682.         vim_memmove(s2 + newoff + offset + addlen,
  683.                    noremapbuf + typeoff + offset, (size_t)(typelen - offset));
  684.         if (noremapbuf != noremapbuf_init)
  685.             vim_free(noremapbuf);
  686.         noremapbuf = s2;
  687.  
  688.         typeoff = newoff;
  689.     }
  690.     typelen += addlen;
  691.  
  692.     /*
  693.      * Adjust noremapbuf[] for the new characters:
  694.      * If noremap  < 0: all the new characters are flagged not remappable
  695.      * If noremap == 0: all the new characters are flagged mappable
  696.      * If noremap  > 0: 'noremap' characters are flagged not remappable, the
  697.      *                    rest mappable
  698.      */
  699.     if (noremap < 0)        /* length not specified */
  700.         noremap = addlen;
  701.     for (i = 0; i < addlen; ++i)
  702.         noremapbuf[typeoff + i + offset] = (noremap-- > 0);
  703.  
  704.                     /* this is only correct for offset == 0! */
  705.     if (nottyped)                        /* the inserted string is not typed */
  706.         typemaplen += addlen;
  707.     if (no_abbr_cnt && offset == 0)        /* and not used for abbreviations */
  708.         no_abbr_cnt += addlen;
  709.  
  710.     return OK;
  711. }
  712.  
  713. /*
  714.  * Return TRUE if there are no characters in the typeahead buffer that have
  715.  * not been typed (result from a mapping or come from ":normal").
  716.  */
  717.     int
  718. typebuf_typed()
  719. {
  720.     return typemaplen == 0;
  721. }
  722.  
  723. /*
  724.  * remove "len" characters from typebuf[typeoff + offset]
  725.  */
  726.     void
  727. del_typebuf(len, offset)
  728.     int    len;
  729.     int    offset;
  730. {
  731.     int        i;
  732.  
  733.     typelen -= len;
  734.     /*
  735.      * Easy case: Just increase typeoff.
  736.      */
  737.     if (offset == 0 && typebuflen - (typeoff + len) >= MAXMAPLEN + 3)
  738.         typeoff += len;
  739.     /*
  740.      * Have to move the characters in typebuf[] and noremapbuf[]
  741.      */
  742.     else
  743.     {
  744.         i = typeoff + offset;
  745.         /*
  746.          * Leave some extra room at the end to avoid reallocation.
  747.          */
  748.         if (typeoff > MAXMAPLEN)
  749.         {
  750.             vim_memmove(typebuf + MAXMAPLEN, typebuf + typeoff, (size_t)offset);
  751.             vim_memmove(noremapbuf + MAXMAPLEN, noremapbuf + typeoff,
  752.                                                               (size_t)offset);
  753.             typeoff = MAXMAPLEN;
  754.         }
  755.             /* adjust typebuf (include the NUL at the end) */
  756.         vim_memmove(typebuf + typeoff + offset, typebuf + i + len,
  757.                                               (size_t)(typelen - offset + 1));
  758.             /* adjust noremapbuf[] */
  759.         vim_memmove(noremapbuf + typeoff + offset, noremapbuf + i + len,
  760.                                                   (size_t)(typelen - offset));
  761.     }
  762.  
  763.     if (typemaplen > offset)            /* adjust typemaplen */
  764.     {
  765.         if (typemaplen < offset + len)
  766.             typemaplen = offset;
  767.         else
  768.             typemaplen -= len;
  769.     }
  770.     if (no_abbr_cnt > offset)            /* adjust no_abbr_cnt */
  771.     {
  772.         if (no_abbr_cnt < offset + len)
  773.             no_abbr_cnt = offset;
  774.         else
  775.             no_abbr_cnt -= len;
  776.     }
  777. }
  778.  
  779. /*
  780.  * Write typed characters to script file.
  781.  * If recording is on put the character in the recordbuffer.
  782.  */
  783.     static void
  784. gotchars(s, len)
  785.     char_u    *s;
  786.     int        len;
  787. {
  788.     int        c;
  789.     char_u    buf[2];
  790.  
  791.     /* remember how many chars were last recorded */
  792.     if (Recording)
  793.         last_recorded_len += len;
  794.  
  795.     buf[1] = NUL;
  796.     while (len--)
  797.     {
  798.         c = *s++;
  799.         updatescript(c);
  800.  
  801.         if (Recording)
  802.         {
  803.             buf[0] = c;
  804.             add_buff(&recordbuff, buf);
  805.         }
  806.     }
  807.  
  808.     /*
  809.      * Do not sync in insert mode, unless cursor key has been used.
  810.      * Also don't sync while reading a script file.
  811.      */
  812.     if ((!(State & (INSERT + CMDLINE)) || arrow_used) &&
  813.                                                   scriptin[curscript] == NULL)
  814.         u_sync();
  815. }
  816.  
  817. /*
  818.  * open new script file for ":so!" command
  819.  * return OK on success, FAIL on error
  820.  */
  821.     int
  822. openscript(name)
  823.     char_u *name;
  824. {
  825.     int oldcurscript;
  826.  
  827.     if (curscript + 1 == NSCRIPT)
  828.     {
  829.         emsg(e_nesting);
  830.         return FAIL;
  831.     }
  832.     else
  833.     {
  834.         if (scriptin[curscript] != NULL)    /* already reading script */
  835.             ++curscript;
  836.                                     /* use NameBuff for expanded name */
  837.         expand_env(name, NameBuff, MAXPATHL);
  838.         if ((scriptin[curscript] = fopen((char *)NameBuff, READBIN)) == NULL)
  839.         {
  840.             emsg2(e_notopen, name);
  841.             if (curscript)
  842.                 --curscript;
  843.             return FAIL;
  844.         }
  845.         /*
  846.          * With command ":g/pat/so! file" we have to execute the
  847.          * commands from the file now.
  848.          */
  849.         if (global_busy)
  850.         {
  851.             State = NORMAL;
  852.             oldcurscript = curscript;
  853.             do
  854.             {
  855.                 normal();
  856.                 vpeekc();            /* check for end of file */
  857.             }
  858.             while (scriptin[oldcurscript]);
  859.             State = CMDLINE;
  860.         }
  861.     }
  862.     return OK;
  863. }
  864.  
  865. /*
  866.  * updatescipt() is called when a character can be written into the script file
  867.  * or when we have waited some time for a character (c == 0)
  868.  *
  869.  * All the changed memfiles are synced if c == 0 or when the number of typed
  870.  * characters reaches 'updatecount' and 'updatecount' is non-zero.
  871.  */
  872.     void
  873. updatescript(c)
  874.     int c;
  875. {
  876.     static int        count = 0;
  877.  
  878.     if (c && scriptout)
  879.         putc(c, scriptout);
  880.     if (c == 0 || (p_uc > 0 && ++count >= p_uc))
  881.     {
  882.         ml_sync_all(c == 0, TRUE);
  883.         count = 0;
  884.     }
  885. }
  886.  
  887. #define K_NEEDMORET -1            /* keylen value for incomplete key-code */
  888. #define M_NEEDMORET -2            /* keylen value for incomplete mapping */
  889.  
  890. static int old_char = -1;        /* ungotten character */
  891.  
  892.     int
  893. vgetc()
  894. {
  895.     int        c, c2;
  896.  
  897.     mod_mask = 0x0;
  898.     last_recorded_len = 0;
  899.     for (;;)                    /* this is done twice if there are modifiers */
  900.     {
  901.         if (mod_mask)            /* no mapping after modifier has been read */
  902.         {
  903.             ++no_mapping;
  904.             ++allow_keys;
  905.         }
  906.         c = vgetorpeek(TRUE);
  907.         if (mod_mask)
  908.         {
  909.             --no_mapping;
  910.             --allow_keys;
  911.         }
  912.  
  913.         /* Get two extra bytes for special keys */
  914.         if (c == K_SPECIAL)
  915.         {
  916.             ++no_mapping;
  917.             c2 = vgetorpeek(TRUE);        /* no mapping for these chars */
  918.             c = vgetorpeek(TRUE);
  919.             --no_mapping;
  920.             if (c2 == KS_MODIFIER)
  921.             {
  922.                 mod_mask = c;
  923.                 continue;
  924.             }
  925.             c = TO_SPECIAL(c2, c);
  926.         }
  927. #ifdef MSDOS
  928.         /*
  929.          * If K_NUL was typed, it is replaced by K_NUL, 3 in mch_inchar().
  930.          * Delete the 3 here.
  931.          */
  932.         else if (c == K_NUL && vpeekc() == 3)
  933.             (void)vgetorpeek(TRUE);
  934. #endif
  935.  
  936.         return check_shifted_spec_key(c);
  937.     }
  938. }
  939.  
  940.     int
  941. vpeekc()
  942. {
  943.     return (vgetorpeek(FALSE));
  944. }
  945.  
  946. /*
  947.  * Call vpeekc() without causing anything to be mapped.
  948.  * Return TRUE if a character is available, FALSE otherwise.
  949.  */
  950.     int
  951. char_avail()
  952. {
  953.     int        retval;
  954.  
  955.     ++no_mapping;
  956.     retval = vgetorpeek(FALSE);
  957.     --no_mapping;
  958.     return (retval != NUL);
  959. }
  960.  
  961.     void
  962. vungetc(c)        /* unget one character (can only be done once!) */
  963.     int        c;
  964. {
  965.     old_char = c;
  966. }
  967.  
  968. /*
  969.  * get a character: 1. from a previously ungotten character
  970.  *                    2. from the stuffbuffer
  971.  *                    3. from the typeahead buffer
  972.  *                    4. from the user
  973.  *
  974.  * if "advance" is TRUE (vgetc()):
  975.  *        really get the character.
  976.  *        KeyTyped is set to TRUE in the case the user typed the key.
  977.  *        KeyStuffed is TRUE if the character comes from the stuff buffer.
  978.  * if "advance" is FALSE (vpeekc()):
  979.  *        just look whether there is a character available.
  980.  */
  981.  
  982.     static int
  983. vgetorpeek(advance)
  984.     int        advance;
  985. {
  986.     register int    c, c1;
  987.     int                keylen = 0;                /* init for gcc */
  988. #ifdef AMIGA
  989.     char_u            *s;
  990. #endif
  991.     register struct mapblock *mp;
  992.     int                timedout = FALSE;        /* waited for more than 1 second
  993.                                                 for mapping to complete */
  994.     int                mapdepth = 0;            /* check for recursive mapping */
  995.     int                mode_deleted = FALSE;    /* set when mode has been deleted */
  996.     int                local_State;
  997.     register int    mlen;
  998.     int                max_mlen;
  999.     int                i;
  1000. #ifdef USE_GUI
  1001.     int                idx;
  1002. #endif
  1003.  
  1004.     /*
  1005.      * VISUAL state is never set, it is used only here, therefore a check is
  1006.      * made if NORMAL state is actually VISUAL state.
  1007.      */
  1008.     local_State = State;
  1009.     if ((State & NORMAL) && VIsual_active)
  1010.         local_State = VISUAL;
  1011.  
  1012. /*
  1013.  * get a character: 1. from a previously ungotten character
  1014.  */
  1015.     if (old_char >= 0)
  1016.     {
  1017.         c = old_char;
  1018.         if (advance)
  1019.             old_char = -1;
  1020.         return c;
  1021.     }
  1022.  
  1023.     if (advance)
  1024.         KeyStuffed = FALSE;
  1025.  
  1026.     init_typebuf();
  1027.     start_stuff();
  1028.     if (advance && typemaplen == 0)
  1029.         Exec_reg = FALSE;
  1030.     do
  1031.     {
  1032. /*
  1033.  * get a character: 2. from the stuffbuffer
  1034.  */
  1035.         c = read_stuff(advance);
  1036.         if (c != NUL && !got_int)
  1037.         {
  1038.             if (advance)
  1039.             {
  1040.                 KeyTyped = FALSE;
  1041.                 KeyStuffed = TRUE;
  1042.             }
  1043.             if (no_abbr_cnt == 0)
  1044.                 no_abbr_cnt = 1;        /* no abbreviations now */
  1045.         }
  1046.         else
  1047.         {
  1048.             /*
  1049.              * Loop until we either find a matching mapped key, or we
  1050.              * are sure that it is not a mapped key.
  1051.              * If a mapped key sequence is found we go back to the start to
  1052.              * try re-mapping.
  1053.              */
  1054.  
  1055.             for (;;)
  1056.             {
  1057.                 mch_breakcheck();            /* check for CTRL-C */
  1058.                 if (got_int)
  1059.                 {
  1060.                     c = inchar(typebuf, MAXMAPLEN, 0L);    /* flush all input */
  1061.                     /*
  1062.                      * If inchar returns TRUE (script file was active) or we are
  1063.                      * inside a mapping, get out of insert mode.
  1064.                      * Otherwise we behave like having gotten a CTRL-C.
  1065.                      * As a result typing CTRL-C in insert mode will
  1066.                      * really insert a CTRL-C.
  1067.                      */
  1068.                     if ((c || typemaplen) && (State & (INSERT + CMDLINE)))
  1069.                         c = ESC;
  1070.                     else
  1071.                         c = Ctrl('C');
  1072.                     flush_buffers(TRUE);        /* flush all typeahead */
  1073.                     break;
  1074.                 }
  1075.                 else if (typelen > 0)    /* check for a mappable key sequence */
  1076.                 {
  1077.                     /*
  1078.                      * walk through the maplist until we find an
  1079.                      * entry that matches.
  1080.                      *
  1081.                      * Don't look for mappings if:
  1082.                      * - timed out
  1083.                      * - no_mapping set: mapping disabled (e.g. for CTRL-V)
  1084.                      * - typebuf[typeoff] should not be remapped
  1085.                      * - in insert or cmdline mode and 'paste' option set
  1086.                      * - waiting for "hit return to continue" and CR or SPACE
  1087.                      *   typed
  1088.                      * - waiting for a char with --more--
  1089.                      * - in Ctrl-X mode, and we get a valid char for that mode
  1090.                      */
  1091.                     mp = NULL;
  1092.                     max_mlen = 0;
  1093.                     if (!timedout && no_mapping == 0 && (typemaplen == 0 ||
  1094.                                 (p_remap && noremapbuf[typeoff] == FALSE))
  1095.                             && !(p_paste && (State & (INSERT + CMDLINE)))
  1096.                             && !(State == HITRETURN && (typebuf[typeoff] == CR
  1097.                                 || typebuf[typeoff] == ' '))
  1098.                             && State != ASKMORE
  1099. #ifdef INSERT_EXPAND
  1100.                             && !(ctrl_x_mode && is_ctrl_x_key(typebuf[typeoff]))
  1101. #endif
  1102.                             )
  1103.                     {
  1104.                         c1 = typebuf[typeoff];
  1105. #ifdef HAVE_LANGMAP
  1106.                         LANGMAP_ADJUST(c1, TRUE);
  1107. #endif
  1108.                         for (mp = maplist.m_next; mp; mp = mp->m_next)
  1109.                         {
  1110.                             /*
  1111.                              * Only consider an entry if
  1112.                              * - the first character matches and
  1113.                              * - it is not an abbreviation and
  1114.                              * - it is for the current state
  1115.                              */
  1116.                             if (        mp->m_keys[0] == c1 &&
  1117.                                         !(mp->m_mode & ABBREV) &&
  1118.                                         (mp->m_mode & local_State))
  1119.                             {
  1120.                                 int        n;
  1121. #ifdef HAVE_LANGMAP
  1122.                                 int        c2;
  1123. #endif
  1124.  
  1125.                                     /* find the match length of this mapping */
  1126.                                 for (mlen = 1; mlen < typelen; ++mlen)
  1127.                                 {
  1128. #ifdef HAVE_LANGMAP
  1129.                                     c2 = typebuf[typeoff + mlen];
  1130.                                     LANGMAP_ADJUST(c2, TRUE);
  1131.                                     if (mp->m_keys[mlen] != c2)
  1132. #else
  1133.                                     if (mp->m_keys[mlen] !=
  1134.                                                     typebuf[typeoff + mlen])
  1135. #endif
  1136.                                         break;
  1137.                                 }
  1138.  
  1139.                                     /* if one of the typed keys cannot be
  1140.                                      * remapped, skip the entry */
  1141.                                 for (n = 0; n < mlen; ++n)
  1142.                                     if (noremapbuf[typeoff + n] == TRUE)
  1143.                                         break;
  1144.                                 if (n != mlen)
  1145.                                     continue;
  1146.  
  1147.                                     /* (partly) match found */
  1148.                                 keylen = mp->m_keylen;
  1149.                                 if (mlen == (keylen > typelen ?
  1150.                                                     typelen : keylen))
  1151.                                 {
  1152.                                         /* partial match, need more chars */
  1153.                                     if (keylen > typelen)
  1154.                                         keylen = M_NEEDMORET;
  1155.                                     break;    
  1156.                                 }
  1157.                                     /* no match, may have to check for
  1158.                                      * termcode at next character */
  1159.                                 if (max_mlen < mlen)
  1160.                                     max_mlen = mlen;
  1161.                             }
  1162.                         }
  1163.                     }
  1164.                     if (mp == NULL)                    /* no match found */
  1165.                     {
  1166.                             /*
  1167.                              * check if we have a terminal code, when
  1168.                              *    mapping is allowed,
  1169.                              *  keys have not been mapped,
  1170.                              *    and not an ESC sequence, not in insert mode or
  1171.                              *        p_ek is on,
  1172.                              *    and when not timed out,
  1173.                              */
  1174.                         if ((no_mapping == 0 || allow_keys != 0) &&
  1175.                                                            (typemaplen == 0 ||
  1176.                                 (p_remap && noremapbuf[typeoff] == FALSE)) &&
  1177.                                             !timedout)
  1178.                             keylen = check_termcode(max_mlen + 1);
  1179.                         else
  1180.                             keylen = 0;
  1181.                         if (keylen == 0)        /* no matching terminal code */
  1182.                         {
  1183. #ifdef AMIGA                    /* check for window bounds report */
  1184.                             if (typemaplen == 0 &&
  1185.                                             (typebuf[typeoff] & 0xff) == CSI)
  1186.                             {
  1187.                                 for (s = typebuf + typeoff + 1;
  1188.                                         s < typebuf + typeoff + typelen &&
  1189.                                         (isdigit(*s) || *s == ';' || *s == ' ');
  1190.                                         ++s)
  1191.                                     ;
  1192.                                 if (*s == 'r' || *s == '|')    /* found one */
  1193.                                 {
  1194.                                     del_typebuf((int)(s + 1 -
  1195.                                                        (typebuf + typeoff)), 0);
  1196.                                         /* get size and redraw screen */
  1197.                                     set_winsize(0, 0, FALSE);
  1198.                                     continue;
  1199.                                 }
  1200.                                 if (*s == NUL)        /* need more characters */
  1201.                                     keylen = K_NEEDMORET;
  1202.                             }
  1203.                             if (keylen >= 0)
  1204. #endif
  1205.                             {
  1206. /*
  1207.  * get a character: 3. from the typeahead buffer
  1208.  */
  1209.                                 c = typebuf[typeoff] & 255;
  1210.                                 if (advance)    /* remove chars from typebuf */
  1211.                                 {
  1212.                                     if (typemaplen)
  1213.                                         KeyTyped = FALSE;
  1214.                                     else
  1215.                                     {
  1216.                                         KeyTyped = TRUE;
  1217.                                         /* write char to script file(s) */
  1218.                                         gotchars(typebuf + typeoff, 1);
  1219.                                     }
  1220.                                     del_typebuf(1, 0);
  1221.                                 }
  1222.                                 break;        /* got character, break for loop */
  1223.                             }
  1224.                         }
  1225.                         if (keylen > 0)        /* full matching terminal code */
  1226.                         {
  1227. #ifdef USE_GUI
  1228.                             if (typebuf[typeoff] == K_SPECIAL &&
  1229.                                               typebuf[typeoff + 1] == KS_MENU)
  1230.                             {
  1231.                                 /*
  1232.                                  * Using a menu causes a break in undo!
  1233.                                  */
  1234.                                 u_sync();
  1235.                                 del_typebuf(3, 0);
  1236.                                 idx = gui_get_menu_index(current_menu,
  1237.                                                                  local_State);
  1238.                                 if (idx != MENU_INDEX_INVALID)
  1239.                                 {
  1240.                                     ins_typebuf(current_menu->strings[idx],
  1241.                                         current_menu->noremap[idx] ? -1 : 0,
  1242.                                         0, TRUE);
  1243.                                 }
  1244.                             }
  1245. #endif /* USE_GUI */
  1246.                             continue;    /* try mapping again */
  1247.                         }
  1248.  
  1249.                         /* partial match: get some more characters */
  1250.                         keylen = K_NEEDMORET;
  1251.                     }
  1252.                         /* complete match */
  1253.                     if (keylen >= 0 && keylen <= typelen)
  1254.                     {
  1255.                                         /* write chars to script file(s) */
  1256.                         if (keylen > typemaplen)
  1257.                             gotchars(typebuf + typeoff + typemaplen,
  1258.                                                         keylen - typemaplen);
  1259.  
  1260.                         del_typebuf(keylen, 0);    /* remove the mapped keys */
  1261.  
  1262.                         /*
  1263.                          * Put the replacement string in front of mapstr.
  1264.                          * The depth check catches ":map x y" and ":map y x".
  1265.                          */
  1266.                         if (++mapdepth >= p_mmd)
  1267.                         {
  1268.                             EMSG("recursive mapping");
  1269.                             if (State == CMDLINE)
  1270.                                 redrawcmdline();
  1271.                             else
  1272.                                 setcursor();
  1273.                             flush_buffers(FALSE);
  1274.                             mapdepth = 0;        /* for next one */
  1275.                             c = -1;
  1276.                             break;
  1277.                         }
  1278.                         /*
  1279.                          * Insert the 'to' part in the typebuf.
  1280.                          * If 'from' field is the same as the start of the
  1281.                          * 'to' field, don't remap this part.
  1282.                          * If m_noremap is set, don't remap the whole 'to'
  1283.                          * part.
  1284.                          */
  1285.                         if (ins_typebuf(mp->m_str, mp->m_noremap ? -1 :
  1286.                                                   STRNCMP(mp->m_str, mp->m_keys,
  1287.                                                    (size_t)keylen) ? 0 : keylen,
  1288.                                                                0, TRUE) == FAIL)
  1289.                         {
  1290.                             c = -1;
  1291.                             break;
  1292.                         }
  1293.                         continue;
  1294.                     }
  1295.                 }
  1296.                 /*
  1297.                  * special case: if we get an <ESC> in insert mode and there
  1298.                  * are no more characters at once, we pretend to go out of
  1299.                  * insert mode.  This prevents the one second delay after
  1300.                  * typing an <ESC>.  If we get something after all, we may
  1301.                  * have to redisplay the mode. That the cursor is in the wrong
  1302.                  * place does not matter.
  1303.                  */
  1304.                 c = 0;
  1305.                 if (advance && typelen == 1 && typebuf[typeoff] == ESC &&
  1306.                          !no_mapping && typemaplen == 0 && (State & INSERT) &&
  1307.                        (p_timeout || (keylen == K_NEEDMORET && p_ttimeout)) &&
  1308.                         (c = inchar(typebuf + typeoff + typelen, 3, 0L)) == 0)
  1309.                 {
  1310.                     if (p_smd)
  1311.                     {
  1312.                         delmode();
  1313.                         mode_deleted = TRUE;
  1314.                     }
  1315.                     if (curwin->w_cursor.col != 0)    /* move cursor one left if
  1316.                                                         possible */
  1317.                     {
  1318.                         if (curwin->w_col)
  1319.                         {
  1320.                             if (did_ai)
  1321.                             {
  1322.                                 /*
  1323.                                  * We are expecting to truncate the trailing
  1324.                                  * white-space, so find the last non-white
  1325.                                  * character -- webb
  1326.                                  */
  1327.                                 colnr_t        col, vcol;
  1328.                                 char_u        *ptr;
  1329.  
  1330.                                 col = vcol = curwin->w_col = 0;
  1331.                                 ptr = ml_get_curline();
  1332.                                 while (col < curwin->w_cursor.col)
  1333.                                 {
  1334.                                     if (!vim_iswhite(ptr[col]))
  1335.                                         curwin->w_col = vcol;
  1336.                                     vcol += lbr_chartabsize(ptr + col,
  1337.                                                                (colnr_t)vcol);
  1338.                                     ++col;
  1339.                                 }
  1340.                                   if (curwin->w_p_nu)
  1341.                                     curwin->w_col += 8;
  1342.                             }
  1343.                             else
  1344.                                 --curwin->w_col;
  1345.                         }
  1346.                         else if (curwin->w_p_wrap && curwin->w_row)
  1347.                         {
  1348.                                 --curwin->w_row;
  1349.                                 curwin->w_col = Columns - 1;
  1350.                         }
  1351.                     }
  1352.                     setcursor();
  1353.                     flushbuf();
  1354.                 }
  1355.                 typelen += c;
  1356.                                                     /* buffer full, don't map */
  1357.                 if (typelen >= typemaplen + MAXMAPLEN)
  1358.                 {
  1359.                     timedout = TRUE;
  1360.                     continue;
  1361.                 }
  1362. /*
  1363.  * get a character: 4. from the user
  1364.  */
  1365.                 /*
  1366.                  * If we have a partial match (and are going to wait for more
  1367.                  * input from the user), show the partially matched characters
  1368.                  * to the user with showcmd -- webb.
  1369.                  */
  1370.                 i = 0;
  1371.                 if (typelen > 0 && (State & (NORMAL | INSERT)) && advance)
  1372.                 {
  1373.                     push_showcmd();
  1374.                     while (i < typelen)
  1375.                         (void)add_to_showcmd(typebuf[typeoff + i++], TRUE);
  1376.                 }
  1377.  
  1378.                 c = inchar(typebuf + typeoff + typelen,
  1379.                         typemaplen + MAXMAPLEN - typelen,
  1380.                         !advance
  1381.                             ? 0
  1382.                             : ((typelen == 0 || !(p_timeout || (p_ttimeout &&
  1383.                                         keylen == K_NEEDMORET)))
  1384.                                     ? -1L
  1385.                                     : ((keylen == K_NEEDMORET && p_ttm >= 0)
  1386.                                             ? p_ttm
  1387.                                             : p_tm)));
  1388.  
  1389.                 if (i)
  1390.                     pop_showcmd();
  1391.  
  1392.                 if (c <= NUL)        /* no character available */
  1393.                 {
  1394.                     if (!advance)
  1395.                         break;
  1396.                     if (typelen)                /* timed out */
  1397.                     {
  1398.                         timedout = TRUE;
  1399.                         continue;
  1400.                     }
  1401.                 }
  1402.                 else
  1403.                 {            /* allow mapping for just typed characters */
  1404.                     while (typebuf[typeoff + typelen] != NUL)
  1405.                         noremapbuf[typeoff + typelen++] = FALSE;
  1406.                 }
  1407.             }        /* for (;;) */
  1408.         }        /* if (!character from stuffbuf) */
  1409.  
  1410.                         /* if advance is FALSE don't loop on NULs */
  1411.     } while (c < 0 || (advance && c == NUL));
  1412.  
  1413.     /*
  1414.      * The "INSERT" message is taken care of here:
  1415.      *   if we return an ESC to exit insert mode, the message is deleted
  1416.      *   if we don't return an ESC but deleted the message before, redisplay it
  1417.      */
  1418.     if (p_smd && (State & INSERT))
  1419.     {
  1420.         if (c == ESC && !mode_deleted && !no_mapping)
  1421.             delmode();
  1422.         else if (c != ESC && mode_deleted)
  1423.             showmode();
  1424.     }
  1425.  
  1426.     return c;
  1427. }
  1428.  
  1429. /*
  1430.  * inchar() - get one character from
  1431.  *        1. a scriptfile
  1432.  *        2. the keyboard
  1433.  *
  1434.  *  As much characters as we can get (upto 'maxlen') are put in buf and
  1435.  *  NUL terminated (buffer length must be 'maxlen' + 1).
  1436.  *  Minimum for 'maxlen' is 3!!!!
  1437.  *
  1438.  *    If we got an interrupt all input is read until none is available.
  1439.  *
  1440.  *  If wait_time == 0  there is no waiting for the char.
  1441.  *  If wait_time == n  we wait for n msec for a character to arrive.
  1442.  *  If wait_time == -1 we wait forever for a character to arrive.
  1443.  *
  1444.  *  Return the number of obtained characters.
  1445.  */
  1446.  
  1447.     static int
  1448. inchar(buf, maxlen, wait_time)
  1449.     char_u    *buf;
  1450.     int        maxlen;
  1451.     long    wait_time;                        /* milli seconds */
  1452. {
  1453.     int                len = 0;            /* init for GCC */
  1454.     int                retesc = FALSE;        /* return ESC with gotint */
  1455.     register int     c;
  1456.     register int    i;
  1457.  
  1458.     if (wait_time == -1L || wait_time > 100L)  /* flush output before waiting */
  1459.     {
  1460.         cursor_on();
  1461.         flushbuf();
  1462.     }
  1463.     /*
  1464.      * Don't reset these when at the hit-return prompt, otherwise a endless
  1465.      * recursive loop may result (write error in swapfile, hit-return, timeout
  1466.      * on char wait, flush swapfile, write error....).
  1467.      */
  1468.     if (State != HITRETURN)
  1469.     {
  1470.         did_outofmem_msg = FALSE;    /* display out of memory message (again) */
  1471.         did_swapwrite_msg = FALSE;    /* display swap file write error again */
  1472.     }
  1473.     undo_off = FALSE;            /* restart undo now */
  1474.  
  1475. /*
  1476.  * first try script file
  1477.  *    If interrupted: Stop reading script files.
  1478.  */
  1479.     c = -1;
  1480.     while (scriptin[curscript] != NULL && c < 0)
  1481.     {
  1482.         if (got_int || (c = getc(scriptin[curscript])) < 0)    /* reached EOF */
  1483.         {
  1484.                 /* when reading script file is interrupted, return an ESC to
  1485.                                     get back to normal mode */
  1486.             if (got_int)
  1487.                 retesc = TRUE;
  1488.             fclose(scriptin[curscript]);
  1489.             scriptin[curscript] = NULL;
  1490.             if (curscript > 0)
  1491.                 --curscript;
  1492.         }
  1493.         else
  1494.         {
  1495.             buf[0] = c;
  1496.             len = 1;
  1497.         }
  1498.     }
  1499.  
  1500.     if (c < 0)            /* did not get a character from script */
  1501.     {
  1502.     /*
  1503.      * If we got an interrupt, skip all previously typed characters and
  1504.      * return TRUE if quit reading script file.
  1505.      */
  1506.         if (got_int)            /* skip typed characters */
  1507.         {
  1508.             while (mch_inchar(buf, maxlen, 0L))
  1509.                 ;
  1510.             return retesc;
  1511.         }
  1512.             /* fill up to a third of the buffer, because each character may be
  1513.              * tripled below */
  1514.         len = mch_inchar(buf, maxlen / 3, wait_time);
  1515.     }
  1516.  
  1517.     /*
  1518.      * Two characters are special: NUL and K_SPECIAL.
  1519.      * Replace       NUL by K_SPECIAL KS_ZERO     K_FILLER
  1520.      * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL K_FILLER
  1521.      * Don't replace K_SPECIAL when reading a script file.
  1522.      */
  1523.     for (i = len; --i >= 0; ++buf)
  1524.     {
  1525.         if (buf[0] == NUL || (buf[0] == K_SPECIAL && c < 0))
  1526.         {
  1527.             vim_memmove(buf + 3, buf + 1, (size_t)i);
  1528.             buf[2] = K_THIRD(buf[0]);
  1529.             buf[1] = K_SECOND(buf[0]);
  1530.             buf[0] = K_SPECIAL;
  1531.             buf += 2;
  1532.             len += 2;
  1533.         }
  1534.     }
  1535.     *buf = NUL;                                /* add trailing NUL */
  1536.     return len;
  1537. }
  1538.  
  1539. /*
  1540.  * map[!]                    : show all key mappings
  1541.  * map[!] {lhs}                : show key mapping for {lhs}
  1542.  * map[!] {lhs} {rhs}        : set key mapping for {lhs} to {rhs}
  1543.  * noremap[!] {lhs} {rhs}    : same, but no remapping for {rhs}
  1544.  * unmap[!] {lhs}            : remove key mapping for {lhs}
  1545.  * abbr                        : show all abbreviations
  1546.  * abbr {lhs}                : show abbreviations for {lhs}
  1547.  * abbr {lhs} {rhs}            : set abbreviation for {lhs} to {rhs}
  1548.  * noreabbr {lhs} {rhs}        : same, but no remapping for {rhs}
  1549.  * unabbr {lhs}                : remove abbreviation for {lhs}
  1550.  *
  1551.  * maptype == 1 for unmap command, 2 for noremap command.
  1552.  *
  1553.  * keys is pointer to any arguments. Note: keys cannot be a read-only string,
  1554.  * it will be modified.
  1555.  *
  1556.  * for :map      mode is NORMAL + VISUAL
  1557.  * for :map!  mode is INSERT + CMDLINE
  1558.  * for :cmap  mode is CMDLINE
  1559.  * for :imap  mode is INSERT 
  1560.  * for :nmap  mode is NORMAL
  1561.  * for :vmap  mode is VISUAL
  1562.  * for :abbr  mode is INSERT + CMDLINE + ABBREV
  1563.  * for :iabbr mode is INSERT + ABBREV
  1564.  * for :cabbr mode is CMDLINE + ABBREV
  1565.  * 
  1566.  * Return 0 for success
  1567.  *          1 for invalid arguments
  1568.  *          2 for no match
  1569.  *          3 for ambiguety
  1570.  *          4 for out of mem
  1571.  */
  1572.     int
  1573. do_map(maptype, keys, mode)
  1574.     int        maptype;
  1575.     char_u    *keys;
  1576.     int        mode;
  1577. {
  1578.     struct mapblock        *mp, *mprev;
  1579.     char_u                *arg;
  1580.     char_u                *p;
  1581.     int                    n;
  1582.     int                    len = 0;        /* init for GCC */
  1583.     char_u                *newstr;
  1584.     int                    hasarg;
  1585.     int                    haskey;
  1586.     int                    did_it = FALSE;
  1587.     int                    abbrev = 0;
  1588.     int                    round;
  1589.     char_u                *keys_buf = NULL;
  1590.     char_u                *arg_buf = NULL;
  1591.     int                    retval = 0;
  1592.     int                    do_backslash;
  1593.  
  1594.     if (mode & ABBREV)        /* not a mapping but an abbreviation */
  1595.     {
  1596.         abbrev = ABBREV;
  1597.         mode &= ~ABBREV;
  1598.     }
  1599. /*
  1600.  * find end of keys and skip CTRL-Vs (and backslashes) in it
  1601.  * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
  1602.  * with :unmap white space is included in the keys, no argument possible
  1603.  */
  1604.     p = keys;
  1605.     do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
  1606.     while (*p && (maptype == 1 || !vim_iswhite(*p)))
  1607.     {
  1608.         if ((p[0] == Ctrl('V') || (do_backslash && p[0] == '\\')) &&
  1609.                                                                   p[1] != NUL)
  1610.             ++p;                /* skip CTRL-V or backslash */
  1611.         ++p;
  1612.     }
  1613.     if (*p != NUL)
  1614.         *p++ = NUL;
  1615.     p = skipwhite(p);
  1616.     arg = p;
  1617.     hasarg = (*arg != NUL);
  1618.     haskey = (*keys != NUL);
  1619.  
  1620.         /* check for :unmap without argument */
  1621.     if (maptype == 1 && !haskey)    
  1622.     {
  1623.         retval = 1;
  1624.         goto theend;
  1625.     }
  1626.  
  1627.     /*
  1628.      * If mapping has been given as ^V<C_UP> say, then replace the term codes
  1629.      * with the appropriate two bytes. If it is a shifted special key, unshift
  1630.      * it too, giving another two bytes.
  1631.      * replace_termcodes() may move the result to allocated memory, which
  1632.      * needs to be freed later (*keys_buf and *arg_buf).
  1633.      * replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
  1634.      */
  1635.     if (haskey)
  1636.         keys = replace_termcodes(keys, &keys_buf, TRUE);
  1637.     if (hasarg)
  1638.         arg = replace_termcodes(arg, &arg_buf, FALSE);
  1639.  
  1640. /*
  1641.  * check arguments and translate function keys
  1642.  */
  1643.     if (haskey)
  1644.     {
  1645.         len = STRLEN(keys);
  1646.         if (len > MAXMAPLEN)            /* maximum length of MAXMAPLEN chars */
  1647.         {
  1648.             retval = 1;
  1649.             goto theend;
  1650.         }
  1651.  
  1652.         if (abbrev)
  1653.         {
  1654.             /*
  1655.              * If an abbreviation ends in a keyword character, the
  1656.              * rest must be all keyword-char or all non-keyword-char.
  1657.              * Otherwise we won't be able to find the start of it in a
  1658.              * vi-compatible way.
  1659.              * An abbrevation cannot contain white space.
  1660.              */
  1661.             if (iswordchar(keys[len - 1]))      /* ends in keyword char */
  1662.                 for (n = 0; n < len - 2; ++n)
  1663.                     if (iswordchar(keys[n]) != iswordchar(keys[len - 2]))
  1664.                     {
  1665.                         retval = 1;
  1666.                         goto theend;
  1667.                     }
  1668.             for (n = 0; n < len; ++n)
  1669.                 if (vim_iswhite(keys[n]))
  1670.                 {
  1671.                     retval = 1;
  1672.                     goto theend;
  1673.                 }
  1674.         }
  1675.     }
  1676.  
  1677.     if (haskey && hasarg && abbrev)        /* if we will add an abbreviation */
  1678.         no_abbr = FALSE;                /* reset flag that indicates there are
  1679.                                                             no abbreviations */
  1680.  
  1681.     if (!haskey || (maptype != 1 && !hasarg))
  1682.         msg_start();
  1683. /*
  1684.  * Find an entry in the maplist that matches.
  1685.  * For :unmap we may loop two times: once to try to unmap an entry with a
  1686.  * matching 'from' part, a second time, if the first fails, to unmap an
  1687.  * entry with a matching 'to' part. This was done to allow ":ab foo bar" to be
  1688.  * unmapped by typing ":unab foo", where "foo" will be replaced by "bar" because
  1689.  * of the abbreviation.
  1690.  */
  1691.     for (round = 0; (round == 0 || maptype == 1) && round <= 1 &&
  1692.                                                  !did_it && !got_int; ++round)
  1693.     {
  1694.         for (mp = maplist.m_next, mprev = &maplist; mp && !got_int;
  1695.                                                   mprev = mp, mp = mp->m_next)
  1696.         {
  1697.                                         /* skip entries with wrong mode */
  1698.             if (!(mp->m_mode & mode) || (mp->m_mode & ABBREV) != abbrev)
  1699.                 continue;
  1700.             if (!haskey)                        /* show all entries */
  1701.             {
  1702.                 showmap(mp);
  1703.                 did_it = TRUE;
  1704.             }
  1705.             else                                /* do we have a match? */
  1706.             {
  1707.                 if (round)        /* second round: try 'to' string for unmap */
  1708.                 {
  1709.                     n = STRLEN(mp->m_str);
  1710.                     p = mp->m_str;
  1711.                 }
  1712.                 else
  1713.                 {
  1714.                     n = mp->m_keylen;
  1715.                     p = mp->m_keys;
  1716.                 }
  1717.                 if (!STRNCMP(p, keys, (size_t)(n < len ? n : len)))
  1718.                 {
  1719.                     if (maptype == 1)            /* delete entry */
  1720.                     {
  1721.                         if (n != len)            /* not a full match */
  1722.                             continue;
  1723.                         /*
  1724.                          * We reset the indicated mode bits. If nothing is
  1725.                          * left the entry is deleted below.
  1726.                          */
  1727.                         mp->m_mode &= (~mode | ABBREV);
  1728.                         did_it = TRUE;            /* remember that we did something */
  1729.                     }
  1730.                     else if (!hasarg)            /* show matching entry */
  1731.                     {
  1732.                         showmap(mp);
  1733.                         did_it = TRUE;
  1734.                     }
  1735.                     else if (n != len)            /* new entry is ambigious */
  1736.                     {
  1737.                         if (abbrev)                /* for abbreviations that's ok */
  1738.                             continue;
  1739.                         retval = 3;
  1740.                         goto theend;
  1741.                     }
  1742.                     else
  1743.                     {
  1744.                         mp->m_mode &= (~mode | ABBREV);        /* remove mode bits */
  1745.                         if (!(mp->m_mode & ~ABBREV) && !did_it)    /* reuse existing entry */
  1746.                         {
  1747.                             newstr = strsave(arg);
  1748.                             if (newstr == NULL)
  1749.                             {
  1750.                                 retval = 4;            /* no mem */
  1751.                                 goto theend;
  1752.                             }
  1753.                             vim_free(mp->m_str);
  1754.                             mp->m_str = newstr;
  1755.                             mp->m_noremap = maptype;
  1756.                             mp->m_mode = mode + abbrev;
  1757.                             did_it = TRUE;
  1758.                         }
  1759.                     }
  1760.                     if (!(mp->m_mode & ~ABBREV))    /* entry can be deleted */
  1761.                     {
  1762.                         map_free(mprev);
  1763.                         mp = mprev;                /* continue with next entry */
  1764.                     }
  1765.                 }
  1766.             }
  1767.         }
  1768.     }
  1769.  
  1770.     if (maptype == 1)                        /* delete entry */
  1771.     {
  1772.         if (!did_it)
  1773.             retval = 2;                        /* no match */
  1774.         goto theend;
  1775.     }
  1776.  
  1777.     if (!haskey || !hasarg)                    /* print entries */
  1778.     {
  1779.         if (!did_it)
  1780.         {
  1781.             if (abbrev)
  1782.                 MSG("No abbreviation found");
  1783.             else
  1784.                 MSG("No mapping found");
  1785.         }
  1786.         goto theend;                        /* listing finished */
  1787.     }
  1788.  
  1789.     if (did_it)                    /* have added the new entry already */
  1790.         goto theend;
  1791. /*
  1792.  * get here when we have to add a new entry
  1793.  */
  1794.         /* allocate a new entry for the maplist */
  1795.     mp = (struct mapblock *)alloc((unsigned)sizeof(struct mapblock));
  1796.     if (mp == NULL)
  1797.     {
  1798.         retval = 4;            /* no mem */
  1799.         goto theend;
  1800.     }
  1801.     mp->m_keys = strsave(keys);
  1802.     mp->m_str = strsave(arg);
  1803.     if (mp->m_keys == NULL || mp->m_str == NULL)
  1804.     {
  1805.         vim_free(mp->m_keys);
  1806.         vim_free(mp->m_str);
  1807.         vim_free(mp);
  1808.         retval = 4;        /* no mem */
  1809.         goto theend;
  1810.     }
  1811.     mp->m_keylen = STRLEN(mp->m_keys);
  1812.     mp->m_noremap = maptype;
  1813.     mp->m_mode = mode + abbrev;
  1814.  
  1815.     /* add the new entry in front of the maplist */
  1816.     mp->m_next = maplist.m_next;
  1817.     maplist.m_next = mp;
  1818.  
  1819. theend:
  1820.     vim_free(keys_buf);
  1821.     vim_free(arg_buf);
  1822.     return retval;
  1823. }
  1824.  
  1825. /*
  1826.  * Delete one entry from the maplist.
  1827.  * The argument is a pointer to the PREVIOUS entry!
  1828.  */
  1829.     static void
  1830. map_free(mprev)
  1831.     struct mapblock        *mprev;
  1832. {
  1833.     struct mapblock        *mp;
  1834.     
  1835.     mp = mprev->m_next;
  1836.     vim_free(mp->m_keys);
  1837.     vim_free(mp->m_str);
  1838.     mprev->m_next = mp->m_next;
  1839.     vim_free(mp);
  1840. }
  1841.  
  1842. /*
  1843.  * Clear all mappings or abbreviations.
  1844.  * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
  1845.  */
  1846.     void
  1847. map_clear(modec, force, abbr)
  1848.     int        modec;
  1849.     int        force;
  1850.     int        abbr;
  1851. {
  1852.     struct mapblock        *mp;
  1853.     int        mode;
  1854.  
  1855.     if (force)            /* :mapclear! */
  1856.         mode = INSERT + CMDLINE;
  1857.     else if (modec == 'i')
  1858.         mode = INSERT;
  1859.     else if (modec == 'n')
  1860.         mode = NORMAL;
  1861.     else if (modec == 'c')
  1862.         mode = CMDLINE;
  1863.     else if (modec == 'v')
  1864.         mode = VISUAL;
  1865.     else
  1866.         mode = VISUAL + NORMAL;
  1867.  
  1868.     for (mp = &maplist; mp->m_next != NULL; )
  1869.     {
  1870.         if (abbr != !(mp->m_next->m_mode & ABBREV) && mp->m_next->m_mode & mode)
  1871.         {
  1872.             mp->m_next->m_mode &= ~mode;
  1873.             if ((mp->m_next->m_mode & ~ABBREV) == 0) /* entry can be deleted */
  1874.             {
  1875.                 map_free(mp);
  1876.                 continue;
  1877.             }
  1878.         }
  1879.         mp = mp->m_next;
  1880.     }
  1881. }
  1882.  
  1883.     static void
  1884. showmap(mp)
  1885.     struct mapblock *mp;
  1886. {
  1887.     int len;
  1888.  
  1889.     if (msg_didout)
  1890.         msg_outchar('\n');
  1891.     if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
  1892.         MSG_OUTSTR("! ");
  1893.     else if (mp->m_mode & INSERT)
  1894.         MSG_OUTSTR("i ");
  1895.     else if (mp->m_mode & CMDLINE)
  1896.         MSG_OUTSTR("c ");
  1897.     else if (!(mp->m_mode & VISUAL))
  1898.         MSG_OUTSTR("n ");
  1899.     else if (!(mp->m_mode & NORMAL))
  1900.         MSG_OUTSTR("v ");
  1901.     else
  1902.         MSG_OUTSTR("  ");
  1903.     /* Get length of what we write */
  1904.     len = msg_outtrans_special(mp->m_keys, TRUE);
  1905.     do
  1906.     {
  1907.         msg_outchar(' ');                /* padd with blanks */
  1908.         ++len;
  1909.     } while (len < 12);
  1910.     if (mp->m_noremap)
  1911.         msg_outchar('*');
  1912.     else
  1913.         msg_outchar(' ');
  1914.     /* Use FALSE below if we only want things like <Up> to show up as such on
  1915.      * the rhs, and not M-x etc, TRUE gets both -- webb
  1916.      */
  1917.     msg_outtrans_special(mp->m_str, TRUE);
  1918.     flushbuf();                            /* show one line at a time */
  1919. }
  1920.  
  1921. /*
  1922.  * Check for an abbreviation.
  1923.  * Cursor is at ptr[col]. When inserting, mincol is where insert started.
  1924.  * "c" is the character typed before check_abbr was called.
  1925.  *
  1926.  * Historic vi practice: The last character of an abbreviation must be an id
  1927.  * character ([a-zA-Z0-9_]). The characters in front of it must be all id
  1928.  * characters or all non-id characters. This allows for abbr. "#i" to
  1929.  * "#include".
  1930.  *
  1931.  * Vim addition: Allow for abbreviations that end in a non-keyword character.
  1932.  * Then there must be white space before the abbr.
  1933.  *
  1934.  * return TRUE if there is an abbreviation, FALSE if not
  1935.  */
  1936.     int
  1937. check_abbr(c, ptr, col, mincol)
  1938.     int        c;
  1939.     char_u    *ptr;
  1940.     int        col;
  1941.     int        mincol;
  1942. {
  1943.     int                len;
  1944.     int                j;
  1945.     char_u            tb[4];
  1946.     struct mapblock *mp;
  1947.     int                is_id = TRUE;
  1948.     int                vim_abbr;
  1949.  
  1950.     if (no_abbr_cnt)        /* abbrev. are not recursive */
  1951.         return FALSE;
  1952.  
  1953.     /*
  1954.      * Check for word before the cursor: If it ends in a keyword char all
  1955.      * chars before it must be al keyword chars or non-keyword chars, but not
  1956.      * white space. If it ends in a non-keyword char we accept any characters
  1957.      * before it except white space.
  1958.      */
  1959.     if (col == 0)                                /* cannot be an abbr. */
  1960.         return FALSE;
  1961.  
  1962.     if (!iswordchar(ptr[col - 1]))
  1963.         vim_abbr = TRUE;                        /* Vim added abbr. */
  1964.     else
  1965.     {
  1966.         vim_abbr = FALSE;                        /* vi compatible abbr. */
  1967.         if (col > 1)
  1968.             is_id = iswordchar(ptr[col - 2]);
  1969.     }
  1970.     for (len = col - 1; len > 0 && !vim_isspace(ptr[len - 1]) &&
  1971.                        (vim_abbr || is_id == iswordchar(ptr[len - 1])); --len)
  1972.         ;
  1973.  
  1974.     if (len < mincol)
  1975.         len = mincol;
  1976.     if (len < col)                /* there is a word in front of the cursor */
  1977.     {
  1978.         ptr += len;
  1979.         len = col - len;
  1980.         for (mp = maplist.m_next; mp; mp = mp->m_next)
  1981.         {
  1982.                     /* find entries with right mode and keys */
  1983.             if ((mp->m_mode & ABBREV) == ABBREV &&
  1984.                         (mp->m_mode & State) &&
  1985.                         mp->m_keylen == len &&
  1986.                         !STRNCMP(mp->m_keys, ptr, (size_t)len))
  1987.                 break;
  1988.         }
  1989.         if (mp)
  1990.         {
  1991.             /*
  1992.              * Found a match:
  1993.              * Insert the rest of the abbreviation in typebuf[].
  1994.              * This goes from end to start.
  1995.              *
  1996.              * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
  1997.              * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL K_FILLER
  1998.              * Characters where IS_SPECIAL() == TRUE: key codes, need
  1999.              * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
  2000.              */
  2001.             j = 0;
  2002.                                             /* special key code, split up */
  2003.             if (IS_SPECIAL(c) || c == K_SPECIAL)
  2004.             {
  2005.                 tb[j++] = K_SPECIAL;
  2006.                 tb[j++] = K_SECOND(c);
  2007.                 c = K_THIRD(c);
  2008.             }
  2009.             else if (c < 0x100  && (c < ' ' || c > '~'))
  2010.                 tb[j++] = Ctrl('V');        /* special char needs CTRL-V */
  2011.             tb[j++] = c;
  2012.             tb[j] = NUL;
  2013.                                             /* insert the last typed char */
  2014.             (void)ins_typebuf(tb, TRUE, 0, TRUE);
  2015.                                             /* insert the to string */
  2016.             (void)ins_typebuf(mp->m_str, mp->m_noremap, 0, TRUE);
  2017.                                             /* no abbrev. for these chars */
  2018.             no_abbr_cnt += STRLEN(mp->m_str) + j + 1;
  2019.  
  2020.             tb[0] = Ctrl('H');
  2021.             tb[1] = NUL;
  2022.             while (len--)                    /* delete the from string */
  2023.                 (void)ins_typebuf(tb, TRUE, 0, TRUE);
  2024.             return TRUE;
  2025.         }
  2026.     }
  2027.     return FALSE;
  2028. }
  2029.  
  2030. /*
  2031.  * Write map commands for the current mappings to an .exrc file.
  2032.  * Return FAIL on error, OK otherwise.
  2033.  */
  2034.     int
  2035. makemap(fd)
  2036.     FILE *fd;
  2037. {
  2038.     struct mapblock *mp;
  2039.     char_u            c1;
  2040.     char_u             *p;
  2041.  
  2042.     for (mp = maplist.m_next; mp; mp = mp->m_next)
  2043.     {
  2044.         c1 = NUL;
  2045.         p = (char_u *)"map";
  2046.         switch (mp->m_mode)
  2047.         {
  2048.         case NORMAL + VISUAL:
  2049.             break;
  2050.         case NORMAL:
  2051.             c1 = 'n';
  2052.             break;
  2053.         case VISUAL:
  2054.             c1 = 'v';
  2055.             break;
  2056.         case CMDLINE + INSERT:
  2057.             p = (char_u *)"map!";
  2058.             break;
  2059.         case CMDLINE:
  2060.             c1 = 'c';
  2061.             break;
  2062.         case INSERT:
  2063.             c1 = 'i';
  2064.             break;
  2065.         case INSERT + CMDLINE + ABBREV:
  2066.             p = (char_u *)"abbr";
  2067.             break;
  2068.         case CMDLINE + ABBREV:
  2069.             c1 = 'c';
  2070.             p = (char_u *)"abbr";
  2071.             break;
  2072.         case INSERT + ABBREV:
  2073.             c1 = 'i';
  2074.             p = (char_u *)"abbr";
  2075.             break;
  2076.         default:
  2077.             EMSG("makemap: Illegal mode");
  2078.             return FAIL;
  2079.         }
  2080.         if (c1 && putc(c1, fd) < 0)
  2081.             return FAIL;
  2082.         if (mp->m_noremap && fprintf(fd, "nore") < 0)
  2083.             return FAIL;
  2084.         if (fprintf(fd, (char *)p) < 0)
  2085.             return FAIL;
  2086.  
  2087.         if (    putc(' ', fd) < 0 || putescstr(fd, mp->m_keys, FALSE) == FAIL ||
  2088.                 putc(' ', fd) < 0 || putescstr(fd, mp->m_str, FALSE) == FAIL ||
  2089. #ifdef USE_CRNL
  2090.                 putc('\r', fd) < 0 ||
  2091. #endif
  2092.                 putc('\n', fd) < 0)
  2093.             return FAIL;
  2094.     }
  2095.     return OK;
  2096. }
  2097.  
  2098. /*
  2099.  * write escape string to file
  2100.  *
  2101.  * return FAIL for failure, OK otherwise
  2102.  */
  2103.     int
  2104. putescstr(fd, str, set)
  2105.     FILE        *fd;
  2106.     char_u        *str;
  2107.     int            set;        /* TRUE for makeset, FALSE for makemap */
  2108. {
  2109.     int        c;
  2110.     int        modifiers;
  2111.  
  2112.     for ( ; *str; ++str)
  2113.     {
  2114.         c = *str;
  2115.         /*
  2116.          * Special key codes have to be translated to be able to make sense
  2117.          * when they are read back.
  2118.          */
  2119.         if (c == K_SPECIAL && !set)
  2120.         {
  2121.             modifiers = 0x0;
  2122.             if (str[1] == KS_MODIFIER)
  2123.             {
  2124.                 modifiers = str[2];
  2125.                 str += 3;
  2126.                 c = *str;
  2127.             }
  2128.             if (c == K_SPECIAL)
  2129.             {
  2130.                 c = TO_SPECIAL(str[1], str[2]);
  2131.                 str += 2;
  2132.             }
  2133.             if (IS_SPECIAL(c) || modifiers)        /* special key */
  2134.             {
  2135.                 fprintf(fd, (char *)get_special_key_name(c, modifiers));
  2136.                 continue;
  2137.             }
  2138.         }
  2139.         /*
  2140.          * A '\n' in a map command should be written as <NL>.
  2141.          * A '\n' in a set command should be written as \^V^J.
  2142.          */
  2143.         if (c == NL)
  2144.         {
  2145.             if (set)
  2146.                 fprintf(fd, "\\\026\n");
  2147.             else
  2148.                 fprintf(fd, "<NL>");
  2149.             continue;
  2150.         }
  2151.         /*
  2152.          * some characters have to be escaped with CTRL-V to
  2153.          * prevent them from misinterpreted in DoOneCmd().
  2154.          * A space, Tab and '"' has to be escaped with a backslash to
  2155.          * prevent it to be misinterpreted in do_set().
  2156.          */
  2157.         if (set && (vim_iswhite(c) || c == '"' || c == '\\'))
  2158.         {
  2159.             if (putc('\\', fd) < 0)
  2160.                 return FAIL;
  2161.         }
  2162.         else if (c < ' ' || c > '~' || c == '|')
  2163.         {
  2164.             if (putc(Ctrl('V'), fd) < 0)
  2165.                 return FAIL;
  2166.         }
  2167.         if (putc(c, fd) < 0)
  2168.             return FAIL;
  2169.     }
  2170.     return OK;
  2171. }
  2172.  
  2173. /*
  2174.  * Check all mappings for the presence of special key codes.
  2175.  * Used after ":set term=xxx".
  2176.  */
  2177.     void
  2178. check_map_keycodes()
  2179. {
  2180.     struct mapblock *mp;
  2181.     char_u             *p;
  2182.     int                i;
  2183.     char_u            buf[3];
  2184.     char_u            *save_name;
  2185.  
  2186.     save_name = sourcing_name;
  2187.     sourcing_name = (char_u *)"mappings";/* don't give error messages */
  2188.     for (mp = maplist.m_next; mp != NULL; mp = mp->m_next)
  2189.     {
  2190.         for (i = 0; i <= 1; ++i)        /* do this twice */
  2191.         {
  2192.             if (i == 0)
  2193.                 p = mp->m_keys;            /* once for the "from" part */
  2194.             else
  2195.                 p = mp->m_str;            /* and once for the "to" part */
  2196.             while (*p)
  2197.             {
  2198.                 if (*p == K_SPECIAL)
  2199.                 {
  2200.                     ++p;
  2201.                     if (*p < 128)        /* only for "normal" termcap entries */
  2202.                     {
  2203.                         buf[0] = p[0];
  2204.                         buf[1] = p[1];
  2205.                         buf[2] = NUL;
  2206.                         (void)add_termcap_entry(buf, FALSE);
  2207.                     }
  2208.                     ++p;
  2209.                 }
  2210.                 ++p;
  2211.             }
  2212.         }
  2213.     }
  2214.     sourcing_name = save_name;
  2215. }
  2216.